#include <linux/bpf.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/version.h>

// 定义事件结构体
struct ssl_read_event {
    u64 timestamp;
    u32 pid;
    u32 tgid;
    u64 ssl_fd;
    u64 buf_addr;
    u64 len;
    char comm[16];
};

// 定义 BPF map
struct {
    __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
    __uint(key_size, sizeof(int));
    __uint(value_size, sizeof(u32));
    __uint(max_entries, 1024);
} events SEC(".maps");

// SSL_read 函数探针
SEC("uprobe/ssl_read")
int ssl_read_probe(struct pt_regs *ctx) {
    struct ssl_read_event event = {};
    
    // 获取当前时间戳
    event.timestamp = bpf_ktime_get_ns();
    
    // 获取进程信息
    event.pid = bpf_get_current_pid_tgid() & 0xFFFFFFFF;
    event.tgid = bpf_get_current_pid_tgid() >> 32;
    
    // 获取进程名
    bpf_get_current_comm(&event.comm, sizeof(event.comm));
    
    // 获取函数参数
    // SSL_read(SSL *ssl, void *buf, int num)
    event.ssl_fd = (u64)PT_REGS_PARM1(ctx);
    event.buf_addr = (u64)PT_REGS_PARM2(ctx);
    event.len = (u64)PT_REGS_PARM3(ctx);
    
    // 发送事件到用户空间
    bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
    
    return 0;
}

// SSL_read 函数返回探针
SEC("uretprobe/ssl_read")
int ssl_read_ret_probe(struct pt_regs *ctx) {
    struct ssl_read_event event = {};
    
    // 获取当前时间戳
    event.timestamp = bpf_ktime_get_ns();
    
    // 获取进程信息
    event.pid = bpf_get_current_pid_tgid() & 0xFFFFFFFF;
    event.tgid = bpf_get_current_pid_tgid() >> 32;
    
    // 获取进程名
    bpf_get_current_comm(&event.comm, sizeof(event.comm));
    
    // 获取返回值（实际读取的字节数）
    event.len = (u64)PT_REGS_RC(ctx);
    
    // 发送事件到用户空间
    bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
    
    return 0;
}

char _license[] SEC("license") = "GPL"; 